//
//  Person.swift
//  EasySwift
//
//  Created by 王隆帅 on 2017/7/10.
//  Copyright © 2017年 王隆帅. All rights reserved.
//

import UIKit

class Person: NSObject {

    var personName = "";
    var isSwift = true;
    
    override init() {
        
        super.init();
    }
    
    // 获取对象的成员变量名称 Swift的成员变量名与属性名是一样的，不会生成下划线的成员变量名
    func allMemberVariables() -> [String] {
        
        var count: UInt32 = 0;
        
        let ivars = class_copyIvarList(self.classForCoder, &count);
        
        var result: [String] = [];
        
        for i in 0 ..< Int(count) {
            
            let ivar = ivars?[i];
            
            let name = ivar_getName(ivar);
            
            if let varName = String.init(utf8String: name!) {
                
                result.append(varName);
            }
        }
        
        return result;
    }
    
    
    // 获取对象的所有方法名
    func allMethods() -> [String: AnyObject] {
        
        var count: UInt32 = 0;
        
        let methods = class_copyMethodList(self.classForCoder, &count);
        
        var resultDict: [String: AnyObject] = [:];

        
        for i in 0 ..< Int(count) {
            
            let method = methods?[i];
            
            let sel = method_getName(method);
            
            let methodName = sel_getName(sel);
            
            let argument = method_getNumberOfArguments(method);
            
            if let strName = String.init(utf8String: methodName!) {
                
               
                resultDict[strName] = argument as AnyObject;
            }
        }
        
        free(methods);
        
        return resultDict;
    }
    
    // 获取对象的所有属性名和属性值
    func allPropertyNamesAndValues() -> [String: AnyObject] {
        
        // 这个类型可以使用CUnsignedInt,对应Swift中的UInt32
        var count: UInt32 = 0;
        
        print(self.classForCoder);
        
        let propereties = class_copyPropertyList(self.classForCoder, &count);
        
        var resultDict: [String: AnyObject] = [:];
        
        for i in 0 ..< Int(count) {
            
            // UnsafeMutablePointer<objc_property_t>是
            // 可变指针，因此properties就是类似数组一样，可以
            // 通过下标获取
            
            let property = propereties?[i];
            let name = property_getName(property);
            
            if let strName = String.init(utf8String: name!) {
                
                if let propertyValue = self.value(forKey: strName) {
                    
                    
                    resultDict[strName] = propertyValue as AnyObject
                }
            }
        }
        
        // 不要忘记释放内存，否则C语言的指针很容易成野指针的
        free(propereties);
        
        return resultDict;
    }
    
    // 获取对象所有属性名
    func allProperties() -> [String] {
        
        // 这个类型可以使用CUnsignedInt,对应Swift中的UInt32
        var count: UInt32 = 0;
        
        print(self.classForCoder);
        
        let propereties = class_copyPropertyList(self.classForCoder, &count);
        
        var propertiesNames: [String] = [];
        
        for i in 0 ..< Int(count) {
        
            // UnsafeMutablePointer<objc_property_t>是
            // 可变指针，因此properties就是类似数组一样，可以
            // 通过下标获取
            
            let property = propereties?[i];
            let name = property_getName(property);
            
            let strName = String.init(utf8String: name!);
            
            propertiesNames.append(strName!);
        }
        
        // 不要忘记释放内存，否则C语言的指针很容易成野指针的
        free(propereties);
        
        return propertiesNames;
    }
    
}
